package auctionhaus
//Authors: Paul Kleczka, Adam Backstrom

import static org.junit.Assert.*
import org.junit.*
import grails.test.mixin.Mock

class BidIntegrationTests {
    Customer seller     //the seller for the listing
    Customer bidderOne  //the first bidder for the listing
    Customer bidderTwo  //the second bidder for the listing

    Listing listing
    
    @Before
    void setUp() {
        //seed database with test data
        seller = new Customer(email: "kleczka@gmail.com",password: "123456", enabled: true)
        assert seller.validate()
        seller.save(flush: true)

        bidderOne = new Customer(email: "adambackstrom@gmail.com",password: "7891011", enabled: true)
        assert bidderOne.validate()
        bidderOne.save(flush: true)

        bidderTwo = new Customer(email: "bborchardt@gmail.com",password: "1234567", enabled: true)
        assert bidderTwo.validate()
        bidderTwo.save(flush: true)

        //The listing has a starting price of 1.0 and and end date 1 day in the future
        listing = new Listing(name: "listing1",
                endDateTime: new Date() + 1,
                startingBidPrice: 1.0f,
                seller: seller)
        assert listing.validate()
        listing.save(flush: true)
    }

    //HW3, UI-1 Named Query
    @Test
    void testNamedQueryBidsByListing(){

        Bid firstBid = new Bid(amount: 1.5f,
                bidDateTime: new Date(),
                bidder: bidderOne)
        listing.addToBids(firstBid)
        listing.save(flush: true)
        assert firstBid.validate()
        def bidList = Bid.bidsByListing(listing).list()
        assertEquals(1, bidList.size())
    }

    
    //Test for validation error when first bid < starting price
    @Test
    void testFirstBidUnderStartingBidPrice() {

        Bid firstBid = new Bid(amount: 0.9f,
                bidDateTime: new Date(),
                bidder: bidderOne,
                listing: listing)
        assert !firstBid.validate()
    }

    //Test for success when the first bid = the set starting price
    @Test
    void testFirstBidAtStartingPrice(){

        Bid firstBid2 = new Bid(amount: 1.0f,
                bidDateTime: new Date(),
                bidder: bidderOne,
                listing: listing)
        assert firstBid2.validate()
    }

    //Test for success when the first bid > the set starting price
    @Test
    void testFirstBidOverStartingPrice(){
        Bid firstBid2 = new Bid(amount: 1.1f,
                bidDateTime: new Date(),
                bidder: bidderOne,
                listing:  listing)
        assert firstBid2.validate()
    }

    //Test that validation succeeds when bid is .5 higher than previous bid for same listing
    // and validation fails when bid is < previous bid for same listing
    //B-5: The Bid amount must be at least .50 higher than the previous Bid for the same listing
    @Test
    void testCurrentBidUnderExisting(){

        Bid firstBid = new Bid(amount: 1.5f,
                               bidDateTime: new Date(),
                               bidder: bidderOne)
        listing.addToBids(firstBid)
        listing.save(flush: true)

        Bid secondBid = new Bid(amount: 1.4f,
                                bidDateTime:  new Date(),
                                bidder: bidderTwo,
                                listing: listing)
        assert !secondBid.validate()
    }

    //Test that validation succeeds when bid is .5 higher than previous bid for same listing
    // and validation fails when bid is equal to previous bid for same listing
    //B-5: The Bid amount must be at least .50 higher than the previous Bid for the same listing
    @Test
    void testCurrentBidAtExisting(){

        Bid firstBid = new Bid(amount: 1.5f,
                bidDateTime: new Date(),
                bidder: bidderOne)
        listing.addToBids(firstBid)
        listing.save(flush: true)

        Bid secondBid = new Bid(amount: 1.5f,
                bidDateTime:  new Date(),
                bidder: bidderTwo,
                listing:  listing)
        assert !secondBid.validate()
    }

    //Test that validation succeeds when bid is .5 higher than previous bid for same listing
    // and validation fails when bid is < .5 higher than previous bid for same listing
    //B-5: The Bid amount must be at least .50 higher than the previous Bid for the same listing
    @Test
    void testCurrentBidNot50CentsOver(){

        Bid firstBid = new Bid(amount: 1.5f,
                bidDateTime: new Date(),
                bidder: bidderOne)
        listing.addToBids(firstBid)
        listing.save(flush: true)

        Bid secondBid = new Bid(amount: 1.7f,
                bidDateTime:  new Date(),
                bidder: bidderTwo,
                listing: listing)
        assert !secondBid.validate()
    }

    //Test that validation succeeds when bid is .5 higher than previous bid for same listing
    // and validation also succeeds on subsequent bid for same listing that is .5 higher than first bid
    //B-5: The Bid amount must be at least .50 higher than the previous Bid for the same listing
    @Test
    void testCurrentBidAt50CentsOver(){

        Bid firstBid = new Bid(amount: 1.5f,
                bidDateTime: new Date(),
                bidder: bidderOne)
        listing.addToBids(firstBid)
        listing.save(flush: true)

        Bid secondBid = new Bid(amount: 2.0f,
                bidDateTime:  new Date(),
                bidder: bidderTwo,
                listing: listing)
        assert secondBid.validate()
    }

    //Test that validation succeeds when bid is .5 higher than previous bid for same listing
    // and validation also succeeds on subsequent bid for same listing that is > .5 higher than first bid
    //B-5: The Bid amount must be at least .50 higher than the previous Bid for the same listing
    @Test
    void testCurrentBidOver50CentsOver(){

        Bid firstBid = new Bid(amount: 1.5f,
                bidDateTime: new Date(),
                bidder: bidderOne)
        listing.addToBids(firstBid)
        listing.save(flush: true)

        Bid secondBid = new Bid(amount: 2.1f,
                bidDateTime:  new Date(),
                bidder: bidderTwo,
                listing: listing)
        assert secondBid.validate()
    }

}
